const db = require("../models/index");
const bcrypt = require("bcryptjs");
const Jwt = require("jsonwebtoken");
const jwt = require("../config/jwt");
const { Op, or } = require("sequelize");
const { regionTime } = require("../utils/regionTime");
const { func } = require("joi");

const User = db.user;
const Project = db.project;
const Need = db.need;
const Bug = db.bug;
const UserProject = db.user_project;
const UserBug = db.user_bug;
const UserNeed = db.user_need;
const NeedHistory = db.needHistory;
const BugHistory = db.bugHistory;

//注册用户
exports.register = async (req, res) => {
  let { username, password, realName, email, gender } = req.body;

  if(realName === null || realName === '' || realName === undefined){
    realName = username;
  }
  if(email === null || email === '' || email === undefined ){
    email = username + '@163.com';
  }
  if(gender === null || gender === '' || gender === undefined ){
    gender = '男';
  }

  // 检查用户名和密码是否提供
  if (!username || !password) {
    return res.status(400).json({
      code: 400,
      errorMsg: "用户名或密码不能为空",
    });
  }

  try {
    // 用户名已存在
    const user = await User.findOne({ where: { username } });
    if (user) {
      return res.status(409).json({
        code: 409,
        errorMsg: "用户名已存在",
      });
    }
    // 用户创建成功;
    password = bcrypt.hashSync(password, 10); // 加密密码
    const newuser = await User.create({
      username,
      password,
      realName,
      email,
      gender,
    });
    res.status(201).json({
      code: 201,
      msg: "用户注册成功",
      data: {
        id: newuser.id,
        username: newuser.username,
        realName: newuser.realName,
        email: newuser.email,
        gender: newuser.gender,
      },
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

// 用户登录
exports.login = async (req, res) => {
  const { username, password } = req.body;

  // 检查用户名和密码是否提供
  if (!username || !password) {
    return res.status(400).json({
      code: 400,
      message: "用户名或密码不能为空",
    });
  }

  try {
    // 查找用户
    let user = await User.findOne({ where: { username } });

    // 如果用户不存在
    if (!user) {
      return res.status(404).json({
        code: 404,
        errorMsg: "用户名或密码错误",
      });
    }

    // 验证密码
    const isMatch = bcrypt.compareSync(password, user.password);

    // 如果对比的结果等于 false, 则证明用户输入的密码错误
    if (!isMatch) {
      return res.status(404).json({
        code: 404,
        errorMsg: "用户名或密码错误",
      });
    }
    // 登录成功
    // 创建一个不包含密码的新用户对象
    const userWithoutPassword = {
      id: user.id,
      username: user.username,
      realName: user.realName,
    };
    // 创建登录token
    const token = Jwt.sign(userWithoutPassword, jwt.jwtSecretKey, {
      expiresIn: jwt.expiresIn,
    });

    res.status(200).json({
      code: 200,
      message: "用户登录成功",
      data: {
        token: "Bearer " + token,
        id: user.id,
      },
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

// 获取用户基本信息
exports.getUserInfo = async (req, res) => {
  // console.log(req.user);
  const userId = req.user.id;

  try {
    // 查找用户
    const user = await User.findOne({
      where: { id: userId },
      attributes: ["username", "realName", "email", "gender"],
    });

    // 如果用户不存在
    if (!user) {
      return res.status(404).json({
        code: 404,
        errorMsg: "获取失败",
      });
    }

    res.status(200).json({
      code: 200,
      msg: "获取成功",
      data: user,
    });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: error.message });
  }
};

// 工作台 获取我的代办工作列表:合并获取我负责的需求列表和缺陷列表为一个数组
exports.getTodo = async (req, res) => {
  const userId = req.user.id; // 获取userId参数

  try {
    // 查询该用户相关的需求和缺陷，status为"规划中"、"实现中"或"新"、"接受/处理"
    const user = await User.findByPk(userId);
    const myNeeds = await user.getMyNeed({
      through: {
        model: UserNeed,
      },
      where: {
        status: {
          [Op.or]: ["规划中", "实现中"],
        },
      },
      attributes: [
        "id",
        "title",
        "status",
        "priority",
        "createdAt",
        "projectName",
        "handlerArray",
      ],
    });

    myNeeds.map((need) => {
      need.handlerArray = JSON.parse(need.handlerArray);
      // 时区转换 2024年5月9日
      need.createdAt = regionTime(need.createdAt);
      need.type = 'need'; // 添加类型标识
    });

    // bug列表
    const myBugs = await user.getMyBug({
      through: {
        model: UserBug,
      },
      where: {
        status: {
          [Op.or]: ["新", "接受/处理"],
        },
      },
      attributes: [
        "id",
        "title",
        "status",
        "priority",
        "severity",
        "createdAt",
        "projectName",
        "handlerArray",
      ],
    });

    myBugs.map((bug) => {
      bug.handlerArray = JSON.parse(bug.handlerArray);
      // 时区转换 2024年5月9日
      bug.createdAt = regionTime(bug.createdAt);
      bug.type = 'bug'; // 添加类型标识
    });

    // 合并需求和缺陷列表
    const myTodo = myNeeds.concat(myBugs);

    // 按项目分组
    const groupedByProject = myTodo.reduce((acc, item) => {
      const projectName = item.projectName || '未分类';
      if (!acc[projectName]) {
        acc[projectName] = [];
      }
      acc[projectName].push(item);
      return acc;
    }, {});

    // 转换为数组格式
    const result = Object.entries(groupedByProject).map(([projectName, items]) => ({
      projectName,
      items
    }));

    res.status(200).json({ code: 200, msg: "获取成功", data: result });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

// 工作台 获取我的已办工作列表:获取我负责的已处理的需求列表和缺陷列表
exports.getMyDone = async (req, res) => {
  const userId = req.user.id; // 获取userId参数

  try {
    const user = await User.findByPk(userId);
    // 需求列表
    const myNeeds = await user.getMyNeed({
      through: {
        model: UserNeed,
      },
      where: {
        status: {
          [Op.or]: ["已实现", "已拒绝"],
        },
      },
      attributes: [
        "id",
        "title",
        "status",
        "priority",
        "createdAt",
        "projectName",
        "handlerArray",
      ],
    });
    myNeeds.map((need) => {
      need.handlerArray = JSON.parse(need.handlerArray);
      // 时区转换 2024年5月9日
      need.createdAt = regionTime(need.createdAt);
      need.type = 'need'; // 添加类型标识
    });
    // bug列表
    const myBugs = await user.getMyBug({
      through: {
        model: UserBug,
      },
      where: {
        status: {
          [Op.or]: ["已解决", "已拒绝", "重新打开"],
        },
      },
      attributes: [
        "id",
        "title",
        "status",
        "priority",
        "severity",
        "createdAt",
        "projectName",
        "handlerArray",
      ],
    });
    myBugs.map((bug) => {
      bug.handlerArray = JSON.parse(bug.handlerArray);
      // 时区转换 2024年5月9日
      bug.createdAt = regionTime(bug.createdAt);
      bug.type = 'bug'; // 添加类型标识
    });
    // 合并需求和缺陷列表
    const myDone = myNeeds.concat(myBugs);

    // 按项目分组
    const groupedByProject = myDone.reduce((acc, item) => {
      const projectName = item.projectName || '未分类';
      if (!acc[projectName]) {
        acc[projectName] = [];
      }
      acc[projectName].push(item);
      return acc;
    }, {});

    // 转换为数组格式
    const result = Object.entries(groupedByProject).map(([projectName, items]) => ({
      projectName,
      items
    }));

    res.status(200).json({ code: 200, msg: "获取成功", data: result });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

// // 工作台 获取我创建的工作列表:合并我创建的需求和缺陷列表
exports.getMyCreate = async (req, res) => {
  const userId = req.user.id; // 获取userId参数

  try {
    const user = await User.findByPk(userId);
    const myNeeds = await user.getMyNeed({
      where: {
        creatorId: userId,
      },
      attributes: [
        "id",
        "title",
        "status",
        "priority",
        "createdAt",
        "projectName",
        "handlerArray",
      ],
    });
    myNeeds.map((need) => {
      need.handlerArray = JSON.parse(need.handlerArray);
      // 时区转换 2024年5月9日
      need.createdAt = regionTime(need.createdAt);
      need.type = 'need'; // 添加类型标识
    });

    const myBugs = await user.getMyBug({
      where: {
        creatorId: userId,
      },
      attributes: [
        "id",
        "title",
        "status",
        "priority",
        "severity",
        "createdAt",
        "projectName",
        "handlerArray",
      ],
    });
    myBugs.map((bug) => {
      bug.handlerArray = JSON.parse(bug.handlerArray);
      // 时区转换 2024年5月9日
      bug.createdAt = regionTime(bug.createdAt);
      bug.type = 'bug'; // 添加类型标识
    });

    const myWork = myNeeds.concat(myBugs);

    // 按项目分组
    const groupedByProject = myWork.reduce((acc, item) => {
      const projectName = item.projectName || '未分类';
      if (!acc[projectName]) {
        acc[projectName] = [];
      }
      acc[projectName].push(item);
      return acc;
    }, {});

    // 转换为数组格式
    const result = Object.entries(groupedByProject).map(([projectName, items]) => ({
      projectName,
      items
    }));

    res.status(200).json({ code: 200, msg: "获取成功", data: result });
  } catch (error) {
    console.error(error);
    res.status(500).json({ code: 500, errorMsg: error.message });
  }
};

//getRemindList 获取提醒列表
exports.getRemindList = async (req, res) => {
  const userId = req.user.id; // 获取userId参数

  try {
    // 查询该用户相关的需求和缺陷
    const userNeeds = await UserNeed.findAll({
      where: {
        userId,
      },
      attributes: ["needId"],
    });

    const userBugs = await UserBug.findAll({
      where: {
        userId,
      },
      attributes: ["bugId"],
    });

    // 获取需求变更历史
    const needHistory = await NeedHistory.findAll({
      where: {
        needId: {
          [Op.in]: userNeeds.map((need) => need.needId),
        },
      },
      attributes: [
        "id",
        "needId",
        "title",
        "changerId",
        "changerName",
        "changedField",
        "status",
        "updatedAt",
        "projectName",
      ],
      order: [["id", "DESC"]],
    });
    // 2024年5月11日
    // 获取缺陷变更历史
    const bugHistory = await BugHistory.findAll({
      where: {
        bugId: {
          [Op.in]: userBugs.map((bug) => bug.bugId),
        },
      },
      attributes: [
        "id",
        "bugId",
        "title",
        "changerId",
        "changerName",
        "changedField",
        "status",
        "updatedAt",
        "projectName",
      ],
      order: [["id", "DESC"]],
    });

    // 映射对象存储字段名和对应的中文翻译
    const fieldTranslations = {
      title: "标题",
      details: "详情",
      priority: "优先级",
      category: "分类",
      startDate: "开始日期",
      endDate: "截止日期",
      status: "状态",
      handlerArray: "处理人",
      comment: "评论",
      creator: "创建人",
    };
    // 格式化历史记录
    function formatHistory(history) {
      for (let i = 0; i < history.length; i++) {
        // 时区转换
        // console.log(history[i].updatedAt);
        // console.log(regionTime(history[i].updatedAt));
        // history[i].updatedAt = regionTime(history[i].updatedAt);   -.-    o.O
        history[i].setDataValue("updatedAt", regionTime(history[i].updatedAt));

        // 格式化changedField
        history[i].changedField = JSON.parse(history[i].changedField);
        // 将字段名转换为中文
        for (let j = 0; j < history[i].changedField.length; j++) {
          const originalField = history[i].changedField[j];
          if (fieldTranslations[originalField]) {
            history[i].changedField[j] = fieldTranslations[originalField];
          }
        }
      }
    }
    // formatHistory(needHistory);
    // formatHistory(bugHistory);

    // 合并需求变更历史和缺陷变更历史
    const remindList = needHistory.concat(bugHistory);
    formatHistory(remindList); // 格式化历史记录

    res.status(200).json(remindList);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: error.message });
  }
};
